//////////////////////////////////////////////////////////////////////////////////
// Company:  
// Engineer:  
// Target Devices:  
// Tool versions:
//
// Create Date:    2011-08-18 15:28
// Project Name:    
// Description:
//
// Dependencies:
//
// Revision: 1.0
// Revision 0.01 - File Created
//
//
//////////////////////////////////////////////////////////////////////////////////
`timescale 1ns/1ns
module arm_ebi_master
#(
    parameter ADDR_WIDTH  = 26,
    parameter DATA_WIDTH  = 16
)
(
    inout [DATA_WIDTH-1:0]      ebi_d,
    output reg [ADDR_WIDTH-1:0] ebi_a,
    output reg                  ebi_ncs,
    output reg                  ebi_nrd,
    output reg                  ebi_nwe
);

/********************************************************\
Parameter
\********************************************************/
localparam U_DLY = 1;
localparam EBI_PERIOD = 50;

/********************************************************\
Signals
\********************************************************/
reg [DATA_WIDTH-1:0]        ebi_data_reg;
reg                         ebi_out_en;

/********************************************************\
main code
\********************************************************/

initial
begin
    ebi_out_en      = 1'b0;
	ebi_data_reg 	= {DATA_WIDTH{1'b0}};
    ebi_a           = {ADDR_WIDTH{1'b1}};
	ebi_ncs		    = 1'b1;
	ebi_nrd 		= 1'b1;
    ebi_nwe         = 1'b1;
end 

assign ebi_d = (ebi_out_en==1'b1)?ebi_data_reg:{DATA_WIDTH{1'bZ}};

/*******************************************************\
	Write data from file to EBI slave
Useage:
	fp= fopen("tmp.dat","r");
	EBI_TASK_WR_FILE(fp,start_addr);
	fclose(fp);
\*******************************************************/	
task EBI_TASK_WR_FILE;
	input integer fp;
    input [ADDR_WIDTH-1:0] start_addr;
	integer state;
	integer	data_h,data_l;
	begin
		state = $fscanf(fp,"%h",data_l);
        state = $fscanf(fp,"%h",data_h);
        ebi_a = start_addr - 2;
		while(state!=-1)
		begin
            ebi_out_en = 1'b1;
            ebi_a = ebi_a + 2;
            ebi_data_reg = (data_h<<8 | data_l);
            ebi_ncs = 1'b0;
            #EBI_PERIOD;
            ebi_nwe = 1'b0;
            #EBI_PERIOD;
            ebi_nwe = 1'b1;
            #EBI_PERIOD;
            ebi_ncs = 1'b1;
            ebi_out_en = 1'b0;
            #EBI_PERIOD;
            state = $fscanf(fp,"%h",data_l);
            state = $fscanf(fp,"%h",data_h);
		end
	end
endtask

/*******************************************************\
	Write 16 bit data to EBI slave
Useage:
	EBI_TASK_WR_WORD(addr,data);
\*******************************************************/	
task EBI_TASK_WR_WORD;
    input [ADDR_WIDTH-1:0] addr;
    input [DATA_WIDTH-1:0] data;
	begin
        ebi_out_en = 1'b1;
        ebi_a = addr;
        ebi_data_reg = data;
        ebi_ncs = 1'b0;
        #EBI_PERIOD;
        ebi_nwe = 1'b0;
        #EBI_PERIOD;
        ebi_nwe = 1'b1;
        #EBI_PERIOD;
        ebi_ncs = 1'b1;
        ebi_out_en = 1'b0;
        #EBI_PERIOD;
	end
endtask

/*******************************************************\
	Read data from EBI slave to file
Useage:
	fp= fopen("tmp.dat","w");
	EBI_TASK_RD2FILE(fp,start_addr,len);
	fclose(fp);
\*******************************************************/	
task EBI_TASK_RD2FILE;
	input integer fp;
    input [ADDR_WIDTH-1:0] start_addr;
    input integer len;
    integer cnt;
	begin
        cnt = 0;
        ebi_a = start_addr - 2;
        while(cnt<len)
        begin
            ebi_a = ebi_a + 2;
            ebi_ncs = 1'b0;
            #EBI_PERIOD;
            ebi_nrd = 1'b0;
            #EBI_PERIOD;
            ebi_nrd = 1'b1;
            $fdisplay(fp,"%h",ebi_d[7:0] );
            $fdisplay(fp,"%h",ebi_d[15:8]);
            cnt = cnt + 2;
            #EBI_PERIOD;
            ebi_ncs = 1'b1;
            #EBI_PERIOD;
        end
	end
endtask

/*******************************************************\
	Read a word from EBI slave
Useage:
	EBI_TASK_RD2FILE(start_addr);
\*******************************************************/	
task EBI_TASK_RD_WORD;
    input [ADDR_WIDTH-1:0] start_addr;
	begin
        ebi_a = start_addr;
        ebi_ncs = 1'b0;
        #EBI_PERIOD;
        ebi_nrd = 1'b0;
        #EBI_PERIOD;
        ebi_nrd = 1'b1;
        #EBI_PERIOD;
        ebi_ncs = 1'b1;
        #EBI_PERIOD;
	end
endtask

endmodule
